package Math;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class _874_WalkingRobotSimulation {
    public int robotSim(int[] commands, int[][] obstacles) {
        Map<Integer, List<Integer>> obsH = new HashMap<>();
        Map<Integer, List<Integer>> obsV = new HashMap<>();
        int[] pos = new int[2];
        int direction = 0;
        int max = 0;
        for (int[] obstacle : obstacles) {
            List<Integer> tmpH = obsH.getOrDefault(obstacle[0],new ArrayList<>());
            List<Integer> tmpV = obsV.getOrDefault(obstacle[1],new ArrayList<>());
            tmpH.add(obstacle[1]);
            tmpV.add(obstacle[0]);
            obsH.put(obstacle[0], tmpH);
            obsV.put(obstacle[1], tmpV);
        }
        for (int command : commands) {
            if (command == -2) {
                direction = (direction + 3) % 4;
            } else if (command == -1) {
                direction = (direction + 1) % 4;
            } else {
                if (direction == 0) {
                    int targetPos = pos[1] + command;
                    if (obsH.containsKey(pos[0])) {
                        int min = targetPos;
                        for (int ob : obsH.get(pos[0])) {
                            if (pos[1] < ob && ob <= min) {
                                    min = ob - 1;
                            }
                        }
                        pos[1] = min;
                    } else {
                        pos[1] = targetPos;
                    }
                } else if (direction == 1) {
                    int targetPos = pos[0] + command;
                    if (obsV.containsKey(pos[1])) {
                        int min = targetPos;
                        for (int ob : obsV.get(pos[1])) {
                            if (pos[0] < ob && ob <= min) {
                                    min = ob - 1;
                            }
                        }
                        pos[0] = min;
                    } else {
                        pos[0] = targetPos;
                    }
                } else if (direction == 2) {
                    int targetPos = pos[1] - command;
                    if (obsH.containsKey(pos[0])) {
                        int min = targetPos;
                        for (int ob : obsH.get(pos[0])) {
                            if (pos[1] > ob && ob >= min) {
                                    min = ob + 1;
                            }
                        }
                        pos[1] = min;
                    } else {
                        pos[1] = targetPos;
                    }
                } else if (direction == 3) {
                    int targetPos = pos[0] - command;
                    if (obsV.containsKey(pos[1])) {
                        int min = targetPos;
                        for (int ob : obsV.get(pos[1])) {
                            if (pos[0] > ob && ob >= min) {
                                    min = ob + 1;
                            }
                        }
                        pos[0] = min;
                    } else {
                        pos[0] = targetPos;
                    }
                }
            }
            int tval = (pos[0] * pos[0]) + (pos[1] * pos[1]);
            if (tval > max) {
                max = tval;
            }
        }
        return max;
    }
}
